package com.hitqz.robot.driver.netty.protocol.decoder;

import com.hitqz.robot.driver.netty.protocol.message.GfMessage;
import com.hitqz.robot.driver.util.GfToolkit;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * 解码器
 */
@Slf4j
public class GfDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        try {
            // 解析头部 0xFF 0xAA
            if (in.readableBytes() < 3) { // 检查头部和长度字节是否足够
                return;
            }
            in.markReaderIndex(); // 标记当前读指针位置
            byte header0 = in.readByte();
            byte header1 = in.readByte();
            if (header0 != (byte) 0xFF || header1 != (byte) 0xAA) {
                in.resetReaderIndex(); // 不是协议头部，重置读指针
                return;
            }
            // 读取长度字节
            byte length = in.readByte();
            // 确保数据包完整
            if (in.readableBytes() < length + 1) { // 包含校验和的长度
                in.resetReaderIndex();
                return;
            }
            // 读取数据部分
            byte[] payload = new byte[length];
            in.readBytes(payload);
            // 读取校验和
            byte checksum = in.readByte();
            GfMessage gfMessage = new GfMessage(length, payload, checksum);
            // 校验数据包的完整性
            if (!gfMessage.doCheck()) {
                // 校验失败，丢弃该包并打印报文
                byte[] fullMessage = new byte[in.readerIndex()];
                in.getBytes(0, fullMessage);
                // 获取远程地址（IP和端口）
                InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
                String ip = remoteAddress.getAddress().getHostAddress();
                int port = remoteAddress.getPort();
                log.warn("[gf]receive [{}:{}] check sum error: {}", ip, port, GfToolkit.bytesToHexString(fullMessage));
                return;
            }
            //将GfMessage 添加到输出列表中,传递给下一个 andler
            out.add(gfMessage);
        } catch (Exception e) {
            in.skipBytes(in.readableBytes());
            log.error("[gf] decoder error: {}", e.getMessage());
        }
    }
}
